﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;

namespace VidoopSecure
{
    /// <summary>
    /// Manages access to VidoopSecure services.
    /// </summary>
    public class VSManager
    {
        /// <summary>
        /// Default Base Url for VidoopSecure
        /// </summary>
        public const string DEFAULT_API_BASE = "https://api.vidoop.com";
        public const string VIDOOP_SECURE_AUTHORIZATION_HEADER_KEY = "authorization";
        
        /// <summary>
        /// Base URL for the VidoopSecure web service.
        /// </summary>
        public string ApiBase 
        { 
            get { return _apiBase; } 
            set { _apiBase = value; } 
        }

        /// <summary>
        /// Customer identifier.
        /// </summary>
        public string CustomerId 
        { 
            get { return _customerId; } 
            set { _customerId = value; } 
        }

        /// <summary>
        /// A <see cref="VidoopSecure.Site" />.
        /// </summary>
        public Site Site 
        { 
            get { return _site; } 
            set { _site = value; } 
        }
    
        public VSManager(string customerId, string apiBase)
        {
            CustomerId = customerId;

            if (!string.IsNullOrEmpty(apiBase))
                ApiBase = apiBase;
            else 
                ApiBase = DEFAULT_API_BASE;

        }


        /// <summary>
        /// Given a site name, sets the site to be used for any subsequent site-specific API calls.
        /// </summary>
        /// <param name="name">Name of the site registered in VidoopSecure.</param>
        /// <param name="username">VidoopSecure API username.</param>
        /// <param name="password">VidoopSecure API password.</param>
        /// <returns>A <see cref="VidoopSecure.Site" />. If any of the parameters are not provided,
        /// the currently-set <see cref="VidoopSecure.Site" /> is returned.</returns>
        public Site SetCurrentSiteById( string siteId, string username, string password) 
        {
            if (!string.IsNullOrEmpty(siteId) && !string.IsNullOrEmpty(username) && !string.IsNullOrEmpty(password)) 
            {
                this.Site = new Site(CustomerId, siteId, username, password);
            }

            return this.Site;
        }

        /// <summary>
        /// Get a VidoopSecure service by name and site.
        /// </summary>
        /// <param name="serviceName">Name of the service to retrieve.</param>
        /// <param name="site">A <see cref="VidoopSecure.Site" />.</param>
        /// <returns>An object of a class derived from <see cref="VidoopSecure.Service" />.</returns>
        /// <seealso cref="VidoopSecure" />
        public Service GetService(string serviceName, Site site) 
        {
            Service service = null;
            Site siteToUse = (site == null) ? Site : site;

            if (siteToUse == null) 
            {   
                 throw new ApplicationException("A site must be provided.");
            } 

            switch (serviceName.ToLower()) 
            {    
                case "captcha":    
                    service = new CaptchaService(this, siteToUse, this.ApiBase);
                    break;

                case "imageshield":
                    service = new ImageShieldService(this, siteToUse, this.ApiBase);
                    break;

                case "enrollment":
                    service = new EnrollmentService(this, siteToUse, this.ApiBase);
                    break;

                case "smsotp":
                    service = new SmsotpService(this, siteToUse, this.ApiBase);
                    break;

                case "voiceotp":
                    service = new VoiceOtpService(this, siteToUse, this.ApiBase);
                    break;

                case "voicepin":
                    service = new VoicePinService(this, siteToUse, this.ApiBase);
                    break;

                case "voiceptl":
                    service = new VoicePtlService(this, siteToUse, this.ApiBase);
                    break;
            }

            return service;
        }


        /// <summary>
        /// Make an API call to the VidoopSecure web service.
        /// </summary>
        /// <param name="url">Absolute URL for the API endpoint.</param>
        /// <param name="method">HTTP method ("GET" or "POST")</param>
        /// <param name="parameters"><see cref="System.Collections.Generic.Dictionary" />
        /// containing parameters to the API call.</param>
        /// <param name="credentials">API user credentials where containing username
        /// and password separated by a color (':').</param>
        /// <returns><see cref="System.Net.HttpWebResponse" /> object.</returns>
        /// <exception cref="VidoopSecureException">Thrown in the event of an
        /// unexpected failure.</exception>
        /// <seealso cref="VidoopSecure" />
        public HttpProxy ApiCall(string url, string method, Dictionary<string, string> parameters,  string credentials) 
        {
            HttpProxy proxy = new HttpProxy();
            proxy.ApiCall(url, method, parameters, credentials);
            return proxy;
        }
            

        private string _apiBase;
        private string _customerId;
        private Site _site;
    }


}
